package game.manager;

import game.Constants;
import game.Event;
import game.Person;
import game.manager.RelationshipManager.Relationship;
import game.util.Util;

import java.util.List;
import java.util.Observable;

public class ScoreManager implements Manager {
	private int score;

	private static ScoreManager manager;

	public static ScoreManager getManager() {
		if (manager == null)
			manager = new ScoreManager();
		return manager;
	}

	@Override
	public void update(Observable o, Object arg) {
		final Event event = (Event) arg;

		switch (event.getType()) {
		case RESET:
			this.initialize();
			break;
		case MINUTE_PASSED:
			this.calculateScore();
			break;
		case RELATIONSHIP_STARTED:
			this.calculateScore();
			break;
		}
	}

	private int getCountMultiplier() {
		final Person user = PersonManager.getManager().getUser();
		final List<Relationship> relationships = RelationshipManager
				.getManager().getRelationships(user);
		final int relationshipCount = relationships.size() - 1;
		return (relationshipCount * Constants.SCORE_COUNT_MULTIPLIER);
	}

	private int getLengthMultiplier(Relationship relationship) {
		int length = relationship.getLength();
		return (length * Constants.SCORE_LENGTH_MINUTE_MULTIPLIER);
	}

	private void calculateScore() {
		final Person user = PersonManager.getManager().getUser();
		final List<Relationship> relationships = RelationshipManager
				.getManager().getRelationships(user);
		final int countMultiplier = this.getCountMultiplier();
		int newScore = 0;

		for (Relationship relationship : relationships) {
			int strength = relationship.getStrength();
			int lengthMultiplier = getLengthMultiplier(relationship);
			newScore += ((100 + countMultiplier + lengthMultiplier) * strength) / 100;
		}

		this.score += newScore;
		Util.log("Score set to " + this.score + "\n");
	}

	@Override
	public void initialize() {
		this.score = 0;
	}

	@Override
	public void gameUpdate() {

	}

	public int getScore() {
		return this.score;
	}
}
